Feat/Add stream pipeline benchmarks and test coverage#349
Conversation
- 补充空程序集输入时不触发 registrar 的回归测试 - 验证忽略空项后按稳定程序集键排序并去重的注册顺序 - 验证跨调用跳过已注册程序集键时仍继续处理剩余新程序集
- 补充 generated registry 为抽象类型时的回退与抛错覆盖 - 补充 generated registry 缺少无参构造器时的回退与抛错覆盖
- 新增 StreamPipelineBenchmarks,覆盖 0/1/4 个 stream pipeline 行为与 FirstItem/DrainAll 观测矩阵 - 内联 GeneratedStreamPipelineBenchmarkRegistry,保持默认 generated-provider benchmark 宿主接线口径 - 更新 benchmark README,补齐 stream pipeline coverage、运行示例与缺口说明
- 新增默认 notification publisher fallback 与缓存行为的回归测试 - 验证容器无 publisher 时继续使用顺序发布语义且不重复查容器
- 新增 StreamingBenchmarks 中的 Mediator steady-state stream 对照与对应 handler 契约。 - 更新 benchmark README 的 stream coverage 与 gap 描述,使其与当前实现一致。
- 更新 cqrs-rewrite 的 active tracking 与 trace,回填本轮多波 batch 的基线、验证与停点结论 - 修复 StreamPipelineBenchmarks 的 trailing whitespace,确保 git diff --check 通过
- 更新 cqrs-rewrite 的 active tracking 与 trace 指标,确保 branch diff 与下一步建议反映当前提交后状态
- 更新 cqrs-rewrite 的 active tracking 与 trace,确保停止时的 branch diff 指标与当前分支状态一致
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
✅ Files skipped from review due to trivial changes (2)
🚧 Files skipped from review as they are similar to previous changes (3)
📜 Recent review details⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
📝 WalkthroughWalkthrough新增 StreamPipelineBenchmarks(BenchmarkDotNet 矩阵:PipelineCount 0/1/4 与观测 FirstItem/DrainAll),扩展 StreamingBenchmarks 支持生成 Mediator 比较,补充生成注册表激活失败、通知发布者回退缓存与注册服务边界的单元测试,并同步更新 README 与迁移追踪文档。 变更清单流管道基准测试框架
Mediator 支持扩展
生成注册表失败与注册边界测试
基准文档与迁移追踪
预期代码审核工作量🎯 3 (中等) | ⏱️ ~20 分钟 可能相关的 PR
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Test ResultsDetails
Insights
Fail Rate
build-and-test: Run #1109
🎉 All tests passed!Slowest Tests
± Comparison with run #1108 at c4a1999 | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 51 runs. Github Test Reporter by CTRF 💚 |
✅
|
| Descriptor | Linter | Files | Fixed | Errors | Warnings | Elapsed time |
|---|---|---|---|---|---|---|
| dotnet-format | yes | 1 | no | 5.3s | ||
| ✅ REPOSITORY | gitleaks | yes | no | no | 8.6s | |
| ✅ REPOSITORY | trufflehog | yes | no | no | 6.38s |
Detailed Issues
⚠️ CSHARP / dotnet-format - 1 error
Welcome to .NET 9.0!
---------------------
SDK Version: 9.0.114
----------------
Installed an ASP.NET Core HTTPS development certificate.
To trust the certificate, run 'dotnet dev-certs https --trust'
Learn about HTTPS: https://aka.ms/dotnet-https
----------------
Write your first app: https://aka.ms/dotnet-hello-world
Find out what's new: https://aka.ms/dotnet-whats-new
Explore documentation: https://aka.ms/dotnet-docs
Report issues and find source on GitHub: https://github.com/dotnet/core
Use 'dotnet --help' to see available commands or visit: https://aka.ms/dotnet-cli
--------------------------------------------------------------------------------------
Unhandled exception: System.Exception: Restore operation failed.
at Microsoft.CodeAnalysis.Tools.CodeFormatter.OpenMSBuildWorkspaceAsync(String solutionOrProjectPath, WorkspaceType workspaceType, Boolean noRestore, Boolean requiresSemantics, String binaryLogPath, Boolean logWorkspaceWarnings, ILogger logger, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Tools.CodeFormatter.FormatWorkspaceAsync(FormatOptions formatOptions, ILogger logger, CancellationToken cancellationToken, String binaryLogPath)
at Microsoft.CodeAnalysis.Tools.FormatCommandCommon.FormatAsync(FormatOptions formatOptions, ILogger`1 logger, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Tools.Commands.RootFormatCommand.FormatCommandDefaultHandler.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
at System.CommandLine.Invocation.InvocationPipeline.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
See detailed reports in MegaLinter artifacts
Set VALIDATE_ALL_CODEBASE: true in mega-linter.yml to validate all sources, not only the diff

Show us your support by starring ⭐ the repository
|
| Filename | Overview |
|---|---|
| GFramework.Cqrs.Benchmarks/Messaging/StreamPipelineBenchmarks.cs | New 527-line benchmark file comparing stream pipeline dispatch (0/1/4 behaviors, FirstItem/DrainAll observation) across direct call, GFramework.CQRS, and MediatR; structure mirrors the existing StreamingBenchmarks pattern cleanly. |
| GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs | Refactored to add FirstItem/DrainAll observation modes and a Mediator benchmark variant; ConsumeFirstItemAsync and DrainAsync helpers replace the old single-mode loop. |
| GFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarFallbackFailureTests.cs | New fixture (correctly marked [NonParallelizable]) covering three fallback-failure paths: unresolvable named fallback, throwing named fallback, and cross-assembly direct fallback; also covers abstract/no-parameterless-ctor registry fallback to reflection. |
| GFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarTests.cs | New fixture with 11 test cases covering deterministic handler order, partial assembly load, generated registry, cache-hit behaviour, and duplicate type filtering; lacks [NonParallelizable] despite mutating the same process-wide statics as the sibling fallback-failure fixture. |
| GFramework.Cqrs.Tests/Cqrs/CqrsNotificationPublisherTests.cs | New tests for custom publisher injection, pre-registered publisher, ambiguous publisher rejection, publisher caching, sequential fallback caching, TaskWhenAll parallel dispatch, zero-handler no-op, and fail-fast sequential semantics. |
| GFramework.Cqrs.Tests/Cqrs/CqrsRegistrationServiceTests.cs | New fixture covering assembly-key deduplication (within call, across calls, null filtering, stable sort order, FullName/SimpleName/ToString fallback chain) for the registration service coordinator. |
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
GFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarTests.cs:17-18
**Missing `[NonParallelizable]` on a fixture that mutates process-wide statics**
`CqrsHandlerRegistrarFallbackFailureTests` carries `[NonParallelizable]` with an explicit comment explaining that it modifies `LoggerFactoryResolver.Provider` and the registrar's static caches. `CqrsHandlerRegistrarTests` modifies the exact same four static caches (`AssemblyMetadataCache`, `RegistryActivationMetadataCache`, `LoadableTypesCache`, `SupportedHandlerInterfacesCache`) in `SetUp`/`TearDown`, and two of its individual test methods also temporarily replace `LoggerFactoryResolver.Provider` inline. If the project ever enables assembly-level or fixture-level parallelism, the competing cache clears and logger-provider swaps will cause intermittent failures that are hard to reproduce. The attribute should be added to match the sibling fixture's explicit isolation guarantee.
Reviews (2): Last reviewed commit: "chore(cqrs-rewrite): 修复PR349评审遗留问题" | Re-trigger Greptile
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md`:
- Around line 78-80: Update the PR anchor text in the numbered list from "PR
`#348`" to "PR `#349`" so the next-step pointer matches the current branch; locate
the occurrence of the string "PR `#348`" in the numbered list block (around the
instruction starting with "再次运行 `$gframework-pr-review`") and replace it with
"PR `#349`", keeping the surrounding wording/formatting intact.
In `@ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md`:
- Around line 42-45: The "当前下一步:" block still references "PR `#348`"; update that
occurrence to "PR `#349`" so the trace's immediate next step matches the current
PR, i.e., replace the text token "PR `#348`" in the "当前下一步:" section with "PR
`#349`" (verify the line containing "先按需要运行 `$gframework-pr-review`,确认 `PR `#348``
latest-head open thread ..." is updated).
In `@GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs`:
- Around line 167-174: The XML doc for the public method Stream_Mediator is
missing a <returns> element; add a <returns> tag to the existing triple-slash
comment for Stream_Mediator describing that the method returns a ValueTask which
completes when the stream observation finishes (i.e., a ValueTask representing
the asynchronous observation of the mediator-created stream returned by
_mediator.CreateStream(_request, CancellationToken.None) and consumed via
ObserveAsync/Observation).
In `@GFramework.Cqrs.Benchmarks/Messaging/StreamPipelineBenchmarks.cs`:
- Around line 146-176: Add missing <returns> XML documentation to the three
public benchmark methods Stream_Baseline, Stream_GFrameworkCqrs, and
Stream_MediatR: each should document that the method returns a ValueTask
representing the asynchronous observation of the response stream produced by the
handler/runtime/mediatr (the task returned from ObserveAsync wrapping the
stream), e.g. mention it returns a ValueTask that completes when the observation
of the response sequence finishes; place the <returns> tag directly above each
method alongside the existing summary.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: e95b62f0-53cb-4f0f-8c1e-c4e70f739563
📒 Files selected for processing (9)
GFramework.Cqrs.Benchmarks/Messaging/StreamPipelineBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Benchmarks/README.mdGFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarFallbackFailureTests.csGFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarTests.csGFramework.Cqrs.Tests/Cqrs/CqrsNotificationPublisherTests.csGFramework.Cqrs.Tests/Cqrs/CqrsRegistrationServiceTests.csai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.mdai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Code Quality & Security
- GitHub Check: Build and Test
- GitHub Check: Analyze (C#)
🧰 Additional context used
📓 Path-based instructions (8)
ai-plan/public/**
📄 CodeRabbit inference engine (AGENTS.md)
ai-plan/public/**: Contributors MUST keep committedai-plan/public/**content safe to publish in Git history
Active tracking and trace files are recovery entrypoints, not append-only changelogs. They MUST stay concise enough forbootto locate the current recovery point quickly
When completed and validated stages begin to accumulate, contributors MUST archive their detailed history out of the activetodos/andtraces/entry files in the same change. Keep only the current recovery point, active facts, active risks, immediate next step, and pointers to the relevant archive files in the default boot path
When a topic is fully complete, move the entire topic directory underai-plan/public/archive/<topic>/and remove it fromai-plan/public/README.mdin the same change
When a task spans multiple commits or is likely to exceed a single agent context window, update both the recovery document and the trace at each meaningful milestone before pausing or handing work off
If subagents are used on a complex task, the main agent MUST capture the delegated scope and any accepted findings in the active recovery document or trace before continuing implementation
Files:
ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.mdai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
ai-plan/**
📄 CodeRabbit inference engine (AGENTS.md)
ai-plan/**: Never write secrets, tokens, credentials, private keys, machine usernames, home-directory paths, hostnames, IP addresses, proprietary URLs, or other sensitive environment details into anyai-plan/**file
Never record absolute file-system paths inai-plan/**; use repository-relative paths, branch names, PR numbers, or stable document identifiers instead
Files:
ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.mdai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
ai-plan/public/**/traces/**
📄 CodeRabbit inference engine (AGENTS.md)
Contributors MUST maintain a matching execution trace under
ai-plan/public/<topic>/traces/for complex work. The trace should record the current date, key decisions, validation milestones, and the immediate next step
Files:
ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
ai-plan/public/**/todos/**
📄 CodeRabbit inference engine (AGENTS.md)
ai-plan/public/**/todos/**: When working from a tracked implementation plan, contributors MUST update the corresponding tracking document underai-plan/public/<topic>/todos/in the same change
Tracking updates MUST reflect completed work, newly discovered issues, validation results, and the next recommended recovery point
For any multi-step refactor, migration, or cross-module task, contributors MUST create or adopt a dedicated recovery document underai-plan/public/<topic>/todos/before making substantive code changes
Recovery documents MUST record the current phase, the active recovery point identifier, known risks, and the next recommended resume step so another contributor or subagent can continue the work safely
Files:
ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
**/*.cs
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.cs: Apply [Log] attribute for automatic logging field and logging helper method generation
Apply [Priority] attribute for automatic priority comparison implementation generation
Apply [GenerateEnumExtensions] attribute to generate enumeration extension capabilities
Apply [ContextAware] attribute to automatically implement IContextAware boilerplate logic
**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///)
XML documentation comments MUST use<summary>,<param>,<returns>,<exception>, and<remarks>where applicable, explaining intent, contract, and usage constraints instead of restating syntax
If a member participates in lifecycle, threading, registration, or disposal behavior, document that behavior explicitly in XML documentation
Add inline comments for non-trivial logic, concurrency or threading behavior, performance-sensitive paths, workarounds and compatibility constraints, edge cases, registration order, lifecycle sequencing, and generated code assumptions
Avoid obvious comments such as// increment i
Methods with non-trivial logic MUST document: The core idea, Key decisions, and Edge case handling, if any
Comments MUST NOT be trivial, redundant, or misleading. Prefer explainingwhyandwhen, not justwhat. Code should remain understandable without requiring external context. Prefer slightly more explanation over too little for framework code
Do not rely on implicit imports. Declare every requiredusingexplicitly
Write null-safe code that respects nullable annotations instead of suppressing warnings by default
Use the namespace patternGFramework.{Module}.{Feature}with PascalCase segments
Follow standard C# naming: Types, methods, properties, events, and constants use PascalCase; Interfaces useIprefix; Parameters and locals use camelCase; Private fields use_camelCase
Use 4 spaces for indentation. Do not use tabs
Use Allman braces
Keepusingdirectives at the top...
Files:
GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Tests/Cqrs/CqrsNotificationPublisherTests.csGFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarFallbackFailureTests.csGFramework.Cqrs.Tests/Cqrs/CqrsRegistrationServiceTests.csGFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarTests.csGFramework.Cqrs.Benchmarks/Messaging/StreamPipelineBenchmarks.cs
**/README.md
📄 CodeRabbit inference engine (AGENTS.md)
**/README.md: Use the canonical filenameREADME.md. Do not introduce newReadMe.mdor other filename variants
A module README MUST describe: the module's purpose, the relationship to adjacent runtime, abstractions, or generator packages, the major subdirectories or subsystems the reader is expected to use, the minimum adoption path, and the correspondingdocs/zh-CN/entry points
If a module's responsibilities, setup, public API surface, generator inputs, or adoption path change, update that module'sREADME.mdin the same change
Files:
GFramework.Cqrs.Benchmarks/README.md
**/Cqrs/**/*.cs
📄 CodeRabbit inference engine (CLAUDE.md)
Use CQRS (Command Query Responsibility Segregation) pattern with the Cqrs naming entry point instead of the historical Mediator alias
Files:
GFramework.Cqrs.Tests/Cqrs/CqrsNotificationPublisherTests.csGFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarFallbackFailureTests.csGFramework.Cqrs.Tests/Cqrs/CqrsRegistrationServiceTests.csGFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarTests.cs
**/*.Tests/**/*.cs
📄 CodeRabbit inference engine (AGENTS.md)
**/*.Tests/**/*.cs: Mirror the source structure in test projects whenever practical
Reuse existing architecture test infrastructure when relevant:ArchitectureTestsBase<T>,SyncTestArchitecture,AsyncTestArchitecture
Files:
GFramework.Cqrs.Tests/Cqrs/CqrsNotificationPublisherTests.csGFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarFallbackFailureTests.csGFramework.Cqrs.Tests/Cqrs/CqrsRegistrationServiceTests.csGFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarTests.cs
🧠 Learnings (2)
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.
Applied to files:
GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Tests/Cqrs/CqrsNotificationPublisherTests.csGFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarFallbackFailureTests.csGFramework.Cqrs.Tests/Cqrs/CqrsRegistrationServiceTests.csGFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarTests.csGFramework.Cqrs.Benchmarks/Messaging/StreamPipelineBenchmarks.cs
📚 Learning: 2026-05-11T06:15:15.057Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 348
File: GFramework.Cqrs.Benchmarks/Messaging/NotificationLifetimeBenchmarks.cs:52-68
Timestamp: 2026-05-11T06:15:15.057Z
Learning: In the GeWuYou/GFramework repo, do not treat a missing [GenerateEnumExtensions] attribute as a code review issue for every enum. Skip the check for:
1) local/private benchmark enums (e.g., enums defined for benchmarks such as HandlerLifetime in GFramework.Cqrs.Benchmarks),
2) enums located in projects that do NOT reference the source-generator abstractions package (the generator won’t apply there), and
3) core framework/runtime-style code paths that AGENTS.md explicitly restricts from using generator-attribute usage.
If an enum falls into any of these cases, do not flag the missing [GenerateEnumExtensions] (it has been triaged as a generalized false positive for these scenarios).
Applied to files:
GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Tests/Cqrs/CqrsNotificationPublisherTests.csGFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarFallbackFailureTests.csGFramework.Cqrs.Tests/Cqrs/CqrsRegistrationServiceTests.csGFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarTests.csGFramework.Cqrs.Benchmarks/Messaging/StreamPipelineBenchmarks.cs
🔇 Additional comments (4)
GFramework.Cqrs.Tests/Cqrs/CqrsNotificationPublisherTests.cs (1)
158-196: LGTM!GFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarTests.cs (1)
9-9: LGTM!Also applies to: 174-240, 768-817
GFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarFallbackFailureTests.cs (1)
141-201: LGTM!Also applies to: 226-242, 343-392
GFramework.Cqrs.Tests/Cqrs/CqrsRegistrationServiceTests.cs (1)
16-33: LGTM!Also applies to: 108-140, 142-182
- 更新 stream benchmark 的 XML 返回值契约 - 修复通知发布器缓存回归测试的误导性安全网 - 同步 ai-plan 中的当前 PR 锚点与验证结果
Summary
Test ResultsDetails
Insights
Fail Rate
build-and-test: Run #1110
🎉 All tests passed!Slowest Tests
± Comparison with run #1109 at 3744e3e | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 52 runs. Github Test Reporter by CTRF 💚 |
- 更新 StreamingBenchmarks 的 XML 返回值注释并收口 README 中的 stream startup/gap 描述。 - 补充 cqrs-rewrite tracking 与 trace,记录 PR GeWuYou#349 合并后的新基线、startup parity 进展与下一恢复点。
Summary by CodeRabbit
发行说明
New Features
Tests
Documentation